#pragma once
extern "C" {
#include "cb.h"
}
#include<assert.h>
#include<stdio.h>
#include <string.h>
using namespace std;
class Fifo
{
    ring_buffer rb;
    public:
    Fifo() {
        /* default 1M size */
        ring_buffer_create(&rb, 20);
    }
    Fifo(int s) {
        /* default 1UL<<s size */
        ring_buffer_create(&rb, s);
    }

    ~Fifo() {
        ring_buffer_free(&rb);
    }
    unsigned long i(void *p, unsigned long size)
    {
        assert(size%4 == 0);
        assert(p);
        if (ring_buffer_count_free_bytes(&rb) < size) {
            printf("Overflow!\n");
            return 0;
        }
        memcpy(ring_buffer_write_address(&rb), p, size);
        ring_buffer_write_advance(&rb, size);
        return size;
    }
    unsigned long o(void *p, unsigned long size)
    {
        assert(size%4 == 0);
        assert(p);

        if (ring_buffer_count_bytes(&rb) < size) {
            printf("Low Storage\n");
            return 0;
        }
        memcpy(p, ring_buffer_read_address(&rb), size);
        ring_buffer_read_advance(&rb, size);
        return size;
    }
    unsigned long free() {
        return ring_buffer_count_free_bytes(&rb);
    }

    bool ready() {
        return (ring_buffer_count_bytes(&rb) > 160*8);
    }
};

